From 098a8c19d8b2177ebe14ac8a1f6f9de93b38f5aa Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Thu, 24 Aug 2006 11:48:35 -0600 Subject: [PATCH] [IA64] pal_halt_light emulatefor domU Signed-off-by: Atsushi SAKAI --- xen/arch/ia64/xen/domain.c | 10 ++++++++++ xen/arch/ia64/xen/hypercall.c | 7 ++++++- xen/include/asm-ia64/domain.h | 1 + xen/include/asm-ia64/vcpu.h | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 2130361cc3..6f2a503f96 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -239,6 +239,12 @@ void startup_cpu_idle_loop(void) # error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)." #endif +void hlt_timer_fn(void *data) +{ + struct vcpu *v = data; + vcpu_unblock(v); +} + struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) { struct vcpu *v; @@ -298,6 +304,9 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) v->arch.breakimm = d->arch.breakimm; v->arch.last_processor = INVALID_PROCESSOR; } + if (!VMX_DOMAIN(v)){ + init_timer(&v->arch.hlt_timer, hlt_timer_fn, v, v->processor); + } return v; } @@ -309,6 +318,7 @@ void relinquish_vcpu_resources(struct vcpu *v) get_order_from_shift(XMAPPEDREGS_SHIFT)); v->arch.privregs = NULL; } + kill_timer(&v->arch.hlt_timer); } void free_vcpu_struct(struct vcpu *v) diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index b5321e030c..203d0211c5 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -235,7 +235,12 @@ fw_hypercall (struct pt_regs *regs) } else { perfc_incrc(pal_halt_light); - do_sched_op_compat(SCHEDOP_yield, 0); + migrate_timer(&v->arch.hlt_timer, + v->processor); + set_timer(&v->arch.hlt_timer, + vcpu_get_next_timer_ns(v)); + do_sched_op_compat(SCHEDOP_block, 0); + stop_timer(&v->arch.hlt_timer); } regs->r8 = 0; regs->r9 = 0; diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index fed8c428e0..394b3bc6ad 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -198,6 +198,7 @@ struct arch_vcpu { unsigned long old_rsc; int mode_flags; fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */ + struct timer hlt_timer; struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ #define INVALID_PROCESSOR INT_MAX diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index 87b3801b2f..7bfc76f761 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -4,6 +4,7 @@ // TODO: Many (or perhaps most) of these should eventually be // static inline functions +#include #include #include #include @@ -15,6 +16,7 @@ typedef int BOOLEAN; struct vcpu; typedef struct vcpu VCPU; typedef cpu_user_regs_t REGS; +extern u64 cycle_to_ns(u64 cycle); /* Note: PSCB stands for Privilegied State Communication Block. */ #define VCPU(_v,_x) (_v->arch.privregs->_x) @@ -183,6 +185,21 @@ itir_mask(UINT64 itir) return (~((1UL << itir_ps(itir)) - 1)); } +static inline s64 +vcpu_get_next_timer_ns(VCPU *vcpu) +{ + s64 vcpu_get_next_timer_ns; + u64 d = PSCBX(vcpu, domain_itm); + u64 now = ia64_get_itc(); + + if (d > now) + vcpu_get_next_timer_ns = cycle_to_ns(d - now) + NOW(); + else + vcpu_get_next_timer_ns = cycle_to_ns(local_cpu_data->itm_delta) + NOW(); + + return vcpu_get_next_timer_ns; +} + #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0) //#define vcpu_quick_region_check(_tr_regions,_ifa) 1 -- 2.30.2